#[cfg(test)]
mod tests {
    use std::collections::HashMap;
    use std::fs::File;
    use std::io::{self, Read};

    use rustica::datatypes::io::IO;
    use rustica::datatypes::maybe::Maybe;
    use rustica::prelude::*;
    use rustica::traits::monad::Monad; // 确保导入 Monad 特性
    use rustica::transformers::StateT;

    #[test]
    fn test() {
        // 创建一个单子值
        let value = Maybe::Just(5);

        // 使用 bind 链接操作
        let result = value.bind(|x| {
            if *x > 0 {
                Maybe::Just(x * 2)
            } else {
                Maybe::Nothing
            }
        });

        assert_eq!(result, Maybe::Just(10));
    }

    #[test]
    fn test2() {
        // 创建 Either 值
        let success: Either<String, i32> = Either::right(42);
        let failure: Either<String, i32> = Either::left("发生错误".to_string());

        // 转换值
        let doubled = success.fmap(|x| x * 2);
        assert_eq!(doubled, Either::right(84));

        // 处理错误
        let result = doubled.right_or(0);
        assert_eq!(result, 84);

        let error_result = failure.right_or(0);
        assert_eq!(error_result, 0);
    }

    #[test]
    fn test3() {
        fn validate_length(input: &str) -> Maybe<String> {
            if input.len() >= 3 {
                Maybe::Just(input.to_string())
            } else {
                Maybe::Nothing
            }
        }

        fn validate_no_special_chars(input: &String) -> Maybe<String> {
            if input
                .chars()
                .all(|c| c.is_alphanumeric() || c.is_whitespace())
            {
                Maybe::Just(input.to_string())
            } else {
                Maybe::Nothing
            }
        }

        let username = "张三";

        // 链接验证
        let validation_result = Maybe::Just(username.to_string())
            .bind(|s| validate_length(s))
            .bind(validate_no_special_chars);

        match validation_result {
            Maybe::Just(valid_name) => println!("有效用户名：{}", valid_name),
            Maybe::Nothing => println!("无效用户名"),
        }
    }

    #[test]
    fn test4() {
        // 可能失败的函数
        fn read_file(path: &str) -> Either<io::Error, String> {
            let mut file = match File::open(path) {
                Ok(file) => file,
                Err(e) => return Either::left(e),
            };

            let mut contents = String::new();
            match file.read_to_string(&mut contents) {
                Ok(_) => Either::right(contents),
                Err(e) => Either::left(e),
            }
        }

        // 尝试读取文件
        let file_contents = read_file("example.txt");

        // 如果读取成功，转换内容
        let processed = file_contents.fmap_right(|contents| contents.lines().count());

        // 处理结果
        match processed {
            Either::Right(line_count) => println!("文件有 {} 行", line_count),
            Either::Left(error) => println!("读取文件错误：{}", error),
        }
    }

    #[test]
    fn test5() {
        // 在 Rustica 中的 IO 单子
        let read_input = IO::new(|| {
            println!("Please entered: ");
            let mut input = String::new();
            std::io::stdin().read_line(&mut input).unwrap();
            input.trim().to_string()
        });

        let print_output = |s: String| {
            IO::new(move || {
                println!("You entered: {}", s);
                s.clone()
            })
        };

        let program = read_input.bind(print_output);
        program.run(); // 读取输入并打印
    }

    #[test]
    fn test6() {
        // 定义状态类型
        type Counter = i32;
        // 创建一个增加计数器的状态操作
        fn increment(amount: i32) -> StateT<Counter, Maybe<(Counter, i32)>, i32> {
            StateT::new(move |s: Counter| {
                let new_state = s + amount;
                Maybe::Just((new_state, new_state)) // 使用 Just 而不是 just
            })
        }

        // 使用状态操作 - 使用 bind_with 而不是 bind
        let computation = increment(5).bind_with(
            |value| {
                // 使用前一个操作的结果
                increment(value)
            },
            |m: Maybe<(i32, i32)>, f| match m {
                Maybe::Just((s, a)) => f((s, a)),
                Maybe::Nothing => Maybe::Nothing,
            },
        );

        // 运行计算，从初始状态 0 开始
        let result = computation.run_state(0);

        // 验证结果
        match result {
            Maybe::Just((final_state, final_value)) => {
                assert_eq!(final_state, 10);
                assert_eq!(final_value, 10);
            }
            Maybe::Nothing => panic!("计算不应该失败"),
        }
    }

    #[test]
    fn test7() {
        // Create a StateT that sets a new state and returns the old one
        let put_state = StateT::<i32, Result<(i32, i32), &str>, i32>::put(100, |t| Ok(t));

        // Run with a specific state
        let result = put_state.run_state(42);
        assert_eq!(result, Ok((100, 42)));
    }

    #[test]
    fn test8() {
        // 应用状态
        #[derive(Clone)]
        struct AppState {
            counter: i32,
            users: HashMap<i32, String>,
            settings: HashMap<String, String>,
        }

        impl AppState {
            fn new() -> Self {
                Self {
                    counter: 0,
                    users: HashMap::new(),
                    settings: HashMap::new(),
                }
            }
        }

        // 状态操作
        fn increment_counter(amount: i32) -> State<AppState, i32> {
            State::new(move |state: AppState| {
                let mut new_state = state.clone();
                new_state.counter += amount;
                (new_state.counter, new_state)
            })
        }

        fn add_user(id: i32, name: String) -> State<AppState, ()> {
            State::new(move |state: AppState| {
                let mut new_state = state.clone();
                new_state.users.insert(id, name.clone());
                ((), new_state)
            })
        }

        fn get_user(id: i32) -> State<AppState, Option<String>> {
            State::new(move |state: AppState| {
                let user = state.users.get(&id).cloned();
                (user, state)
            })
        }

        fn set_setting(key: String, value: String) -> State<AppState, ()> {
            State::new(move |state: AppState| {
                let mut new_state = state.clone();
                new_state.settings.insert(key.clone(), value.clone());
                ((), new_state)
            })
        }

        fn get_setting(key: String) -> State<AppState, Option<String>> {
            State::new(move |state: AppState| {
                let setting = state.settings.get(&key).cloned();
                (setting, state)
            })
        }

        // 组合状态操作
        let program = increment_counter(5)
            .bind(|_| add_user(1, "张三".to_string()))
            .bind(|_| add_user(2, "李四".to_string()))
            .bind(|_| set_setting("theme".to_string(), "dark".to_string()))
            .bind(|_| get_user(1))
            .bind(|user| match user {
                Some(name) => {
                    println!("用户名: {}", name);
                    get_setting("theme".to_string())
                }
                None => State::pure(None),
            });

        // 执行程序
        let initial_state = AppState::new();
        let (result, final_state) = program.run_state(initial_state);

        assert_eq!(result, Some("dark".to_string()));
        assert_eq!(final_state.counter, 5);
        assert_eq!(final_state.users.len(), 2);
        assert_eq!(final_state.settings.len(), 1);
    }
}
